import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;

public class GameRankSystem {
    private final ConcurrentHashMap<String, Long> hash = new ConcurrentHashMap<>();

    // 分数排名存储（分数 -> 玩家ID集合），使用线程安全的跳表实现，分数按降序排列
    private final ConcurrentSkipListMap<Long, Set<String>> rankList =
            new ConcurrentSkipListMap<>(Comparator.reverseOrder());

    public void addScore(String playerId,long score) {
        hash.compute(playerId, (id, oldScore) -> {
            if (oldScore != null) {
                // 如果已有分数，先从排名中移除旧分数
                removePlayerFromRankings(id, oldScore);
            }
            // 更新分数并添加到新排名
            addPlayerToRankings(id, score);
            return score;
        });
    }

    private void addPlayerToRankings(String playerId, long score) {
        rankList.compute(score,(oldScore,players)->{
            if(players==null) {
                players=ConcurrentHashMap.newKeySet();
            }
            players.add(playerId);
            return players;
        });
    }

    private void removePlayerFromRankings(String playerId, long score) {
        rankList.computeIfPresent(score,(s,players)->{
            hash.remove(playerId);
            return players.isEmpty()? null:players;
        });
    }

    public int getPlayerRank(String playerId) {
        Long score = hash.get(playerId);
        if(score==null) {
            return -1;
        }
        int rank=1;
        for(Map.Entry<Long, Set<String>> entry : rankList.headMap(score).entrySet()) {
            rank+=entry.getValue().size();
        }
        Set<String> sameScorePlayers = rankList.get(score);
        if (sameScorePlayers!=null) {
            for(String players:sameScorePlayers) {
                if(playerId.equals(players)) {
                    break;
                }
                rank++;
            }
        }
        return rank;
    }
    public List<String> getTopN(int n ) {
        List<String> topN = new ArrayList<>();
        int count=0;
        for(Map.Entry<Long, Set<String>> entry : rankList.entrySet()) {
            for (String player : entry.getValue()) {
                if(count>=n) {
                    break;
                }
                topN.add(player);
                count++;
            }
            //双层break跳出循环。
            if(count>=n) {
                break;
            }
        }
        return topN;
    }

}
